import {
	http
} from '@/utils/http.js';
import envData from "@/utils/env.js"
// toast 弹窗
export const toast = ({
	title,
	time = 2000,
	icon = 'none'
}, ...arg) => {
	if (!title) return
	uni.showToast({
		title,
		icon,
		duration: time,
	})
	const [callback] = arg
	if (!!callback) {
		let timeID = setTimeout(() => {
			clearTimeout(timeID)
			timeID = null
			callback()
		}, time)
	}
}

export const request = ({ url, method, data }) => {
	return http('/api' + url, method || "POST", data)
}


let IS_LOADING = false // 是否正在展示loading
export const showLoading = (title = '正在加载...') => {
	let hideLoading = () => {
		if (!IS_LOADING) return
		IS_LOADING = false
		uni.hideLoading()
		if (hideLoading) hideLoading = null
	}
	if (IS_LOADING) return hideLoading
	uni.showLoading({
		title,
		mask: true,
		success: () => IS_LOADING = true
	})
	return hideLoading
}

export function rpx2Px(v, joinUnit = true) {
	v = v.replace(/[^\d]/gi, '')
	v = Number(v)
	if (isNaN(v)) v = 0
	const val = uni.upx2px(v)
	if (!joinUnit) return val
	return val + 'px'
}


// 0->h5 1->app 2->微信小程序
function getPlatform() {
	let value = 0
	// #ifdef APP-PLUS
	value = 1
	// #endif
	// #ifdef MP-WEIXIN
	value = 2
	// #endif
	return value
}

// 判断当前是否是development
export const PLATFORM = {
	__value__: getPlatform(),
	get isH5() {
		return this.__value__ === 0;
	},
	get isApp() {
		return this.__value__ === 1;
	},
	get isWx() {
		return this.__value__ === 2;
	},
	get isIos() {
		return uni.getSystemInfoSync().platform.toUpperCase() === 'IOS';
	},
	// app 是否检测权限
	usePermission: true
}


export const uploadFile = (file, loading = true) => new Promise(resolve => {
	let hide = null
	if (loading) hide = showLoading("正在上传")
	uni.uploadFile({
		url: envData.BASE_URL + "/api/upload/image",
		filePath: file,
		name: "file",
		header: {
			token: uni.getStorageSync("token") || ""
		},
		complete: () => hide && hide(),
		success: res => {
			if (res.statusCode === 200) {
				const data = JSON.parse(res.data)
				if (!data) return resolve([true, null])
				return resolve([null, data.data])
			}
			return resolve([res || true, null])
		},
		fail: err => {
			return resolve([err || true, null])
		}
	})
})


/**
 * 封装并发请求
 * @param options {{payload: [T]}[]}
 * 配置项 {payload,hook} payload为数组 会展开依次填充到异步函数中 hook为当前配置项需要传递的自定义参数
 * @param maxLen 最大并发数
 * @param reqFunc 需要执行的异步函数
 * @param cb 没发task执行成功回调
 * @param onError 请求错误执行的回调
 * @returns {Promise<unknown>}
 */
export function useConcurrence({ options, maxLen = 6, reqFunc, cb = null, onError }) {
	return new Promise(resolve => {
		if (!Array.isArray(options)) throw new Error('options type must be [Array]')
		const { length: MAX } = options
		let index = 0
		let count = 0
		const result = []

		async function request() {
			if (index === MAX) return
			let curIndex = index
			index++
			const {
				payload,
				hook
			} = options[curIndex]
			try {
				const resp = await reqFunc(...payload)
				result[curIndex] = resp
				cb && cb(resp, hook)
			} catch (error) {
				result[curIndex] = error
				cb && cb(error, hook)
			} finally {
				count++
				if (count < MAX) {
					await request()
				} else {
					resolve(result)
				}
			}
		}

		if (maxLen === -1) {
			maxLen = MAX
		} else {
			maxLen = Math.min(maxLen, MAX)
		}
		for (let i = 0; i < maxLen; i++) {
			request().catch(error => onError && onError(error))
		}
	})
}

// 拼接 0
export const patchZero = value => {
	value = Number(value)
	if (isNaN(value)) return '0'
	return ('0' + value).slice(-2)
}

export const isNumber = (v) => {
	v = v.toString()
	if (!v) return false
	return /^[0-9]*$/.test(v)
}

export const isInt = (v) => isNumber(v)

export const createDate = (...args) => {
	if (!args.length) return new Date()
	if (args.length > 1) return new Date(...args)
	let [timestamp] = args
	if (timestamp instanceof Date) return timestamp
	if (!timestamp) return new Date()
	if (typeof timestamp === "string" && isInt(timestamp)) timestamp = Number(timestamp);
	if (typeof timestamp === "string") {
		timestamp = timestamp.replace(/-/g, "/")
	}
	return new Date(timestamp)
}

export const formatDate = (timestamp, format = "YYYY-MM-DD") => {
	if (!format) format = "YYYY-MM-DD";
	const date = createDate(timestamp)
	const [year, month, day, hour, minutes, seconds] = [
		date.getFullYear(),
		date.getMonth() + 1,
		date.getDate(),
		date.getHours(),
		date.getMinutes(),
		date.getSeconds()
	]
	return format.replace(/YYYY/i, `${year}`)
		.replace(/MM/, `${patchZero(month)}`)
		.replace(/DD/i, `${patchZero(day)}`)
		.replace(/hh/i, `${patchZero(hour)}`)
		.replace(/mm/, `${patchZero(minutes)}`)
		.replace(/ss/, `${patchZero(seconds)}`)
}

export const delay = (time = 200, func) => new Promise(resolve => {
	setTimeout(() => {
		func && func()
		resolve()
	}, time || 200)
})

export const checkIsDev = () => {
	const accountInfo = wx.getAccountInfoSync()
	const { envVersion } = accountInfo.miniProgram
	return envVersion === "develop"
}